/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.web.servlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vacoor.nothing.web.util.SettingsUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author vacoor
 */
public class WebContextFilter implements Filter {
    private static final Logger LOG = LoggerFactory.getLogger(WebContextFilter.class);
    private ServletContext servletContext;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        servletContext = filterConfig.getServletContext();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        LOG.debug(buildLogMessage(req, -1, false, -1));
        WebRequestContext context = null;
        try {
            context = new WebRequestContext(req, resp, servletContext).bind();
            req.setAttribute("cfg", SettingsUtils.getProperties());

            chain.doFilter(request, response);
        } finally {
            if (null != context) {
                context.unbind();
            }
        }
    }

    @Override
    public void destroy() {
    }

    private static String buildLogMessage(HttpServletRequest httpRequest, long duration, boolean systemError, int responseSize) {
        final StringBuilder msg = new StringBuilder();

        String remoteAddr = httpRequest.getRemoteAddr();
        if ("0:0:0:0:0:0:0:1".equals(remoteAddr)) {
            remoteAddr = "127.0.0.1";
        }
        msg.append("remoteAddr = ").append(remoteAddr);
        try {
            //  msg.append("(").append(new TaobaoIPLocator().locate(remoteAddr)).append(")");
        } catch (Exception ignore) {/* ignore */}

        final String forwardedFor = httpRequest.getHeader("X-Forwarded-For");
        if (forwardedFor != null) {
            msg.append(", forwardedFor = ").append(forwardedFor);
        }
        // msg.append(", request = ").append(httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()));
        msg.append(", request = ").append(httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()));
        if (httpRequest.getQueryString() != null) {
            msg.append('?').append(httpRequest.getQueryString());
        }
        msg.append(' ').append(httpRequest.getMethod());
        msg.append(": ").append(duration).append(" ms");
        if (systemError) {
            msg.append(", erreur");
        }
        msg.append(", ").append(responseSize / 1024).append(" Ko");
        return msg.toString();
    }
}
